package com.tau.iplayer.client.widgets;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.MouseOutEvent;
import com.google.gwt.event.dom.client.MouseOutHandler;
import com.google.gwt.event.dom.client.MouseOverEvent;
import com.google.gwt.event.dom.client.MouseOverHandler;
import com.google.gwt.resources.client.ImageResource;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.AbsolutePanel;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Image;
import com.google.gwt.user.client.ui.Panel;
import com.google.gwt.user.client.ui.SimplePanel;
import com.tau.iplayer.client.IPlayer;
import com.tau.iplayer.client.resources.IPlayerResources;
import com.tau.iplayer.client.models.Track;

public class RatingViewer extends Composite {

	private static final int MAX_RATING = 5;
	private boolean isReadOnly = false;
	private Panel panel;
	private IPlayerResources clientBundle = GWT.create(IPlayerResources.class);

	private Image[] imgArray = new Image[MAX_RATING];
	private Track track;

	private IPlayer iPlayer;

	public RatingViewer(IPlayer iPlayer, Track track, boolean isReadOnly) {
		this.isReadOnly = isReadOnly;
		this.iPlayer = iPlayer;
		this.track = track;
		if (!isReadOnly) {
			panel = new HorizontalPanel();
			for (int i = 0; i < MAX_RATING; i++) {
				final int ratingNum = i + 1;
				Image image = new Image();
				imgArray[i] = image;
				image.addMouseOverHandler(new MouseOverHandler() {

					@Override
					public void onMouseOver(MouseOverEvent event) {
						handleMouseOver(ratingNum);
					}
				});
				image.addClickHandler(new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						handleMouseClick(ratingNum);
					}
				});
				image.addMouseOutHandler(new MouseOutHandler() {

					@Override
					public void onMouseOut(MouseOutEvent event) {
						displayRating(RatingViewer.this.track.getRating());
					}
				});
				panel.add(image);
			}
		} else {
			panel = new AbsolutePanel();

			ImageResource resource = clientBundle.ratingOff();
			Image ratingOffImage = new Image(resource);
			panel.setSize((ratingOffImage.getWidth() * MAX_RATING) + "px",
					ratingOffImage.getHeight() + "px");
			panel.setStyleName("bgOff-repeat");
		}
		displayRating(track.getRating());
		initWidget(panel);
	}

	private void handleMouseClick(int ratingNum) {
		setRating(ratingNum);
	}

	private void handleMouseOver(int ratingNum) {
		displayRating(ratingNum);
	}

	/**
	 * @param rating
	 */
	private void displayRating(double rating) {
		if (!isReadOnly) {
			for (int i = 0; i < MAX_RATING; i++) {
				ImageResource resource = (i + 1 <= rating) ? clientBundle
						.ratingOn() : clientBundle.ratingOff();
				imgArray[i].setResource(resource);
			}
		} else {
			ImageResource resource = clientBundle.ratingOn();
			Image ratingOnImage = new Image(resource);
			int width = (int) ((track.getRating() / 5) * (ratingOnImage
					.getWidth() * MAX_RATING));
			SimplePanel onPanel = new SimplePanel();
			onPanel.setStyleName("bgOn-repeat");
			onPanel.setSize(width + "px", ratingOnImage.getHeight() + "px");
			panel.add(onPanel);
		}
	}

	/**
	 * @param rating
	 *            the rating to set
	 */
	public void setRating(int rating) {
		track.setRating(rating);
		displayRating(track.getRating());
		track.updateTrack(iPlayer.getViewer(), new AsyncCallback<Void>() {

			@Override
			public void onSuccess(Void result) {
				// TODO Auto-generated method stub

			}

			@Override
			public void onFailure(Throwable caught) {
				// TODO Auto-generated method stub

			}
		});
	}

	/**
	 * @param isReadOnly
	 *            the isReadOnly to set
	 */
	public void setReadOnly(boolean isReadOnly) {
		this.isReadOnly = isReadOnly;
	}

	/**
	 * @return the isReadOnly
	 */
	public boolean isReadOnly() {
		return isReadOnly;
	}

}
